float4x4 World;
float4x4 View;
float4x4 Projection;

bool InfiniteDepth = false;

float NearPlane;
float FarPlane;

float SpecularIntensity;
float SpecularPower;

texture Texture;
sampler textureSampler = sampler_state
{
    Texture = <Texture>;
    AddressU = Wrap;
    AddressV = Wrap;
    MinFilter = Anisotropic;
    MagFilter = Anisotropic;
};

struct VertexShaderInput
{
    float4 Position : POSITION0;
    float3 Normal   : NORMAL0;
    float2 TexCoord : TEXCOORD0;
};

struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float2 TexCoord : TEXCOORD0;
    float  Depth    : TEXCOORD1;
    float3 Normal   : TEXCOORD2;
};

struct PixelShaderOutput
{
    float4 Normal : COLOR0;
    float4 Depth  : COLOR1;
    float4 Color  : COLOR2;
};

VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
    VertexShaderOutput output;

    output.Position = mul(mul(mul(input.Position, World), View), Projection);
    output.TexCoord = input.TexCoord;
    output.Normal = mul(input.Normal, World);
    output.Depth = output.Position.z / FarPlane;

    return output;
}

PixelShaderOutput PixelShaderFunction(VertexShaderOutput input)
{
    PixelShaderOutput output;

    output.Normal.xyz = normalize(input.Normal) * .5 + .5;
    output.Normal.a = SpecularIntensity;

    output.Depth = InfiniteDepth ? 1 : input.Depth;

    output.Color.rgb = tex2D(textureSampler, input.TexCoord);
    output.Color.a = SpecularPower;

    return output;
}

technique Technique1
{
    pass Pass1
    {
        VertexShader = compile vs_2_0 VertexShaderFunction();
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}
